#!/bin/bash

setup-tests() {
    # Bring up the server
    docker-spire-server-up spire-server

    # Bootstrap the agent
    log-debug "bootstrapping downstream agent..."
    docker compose exec -T spire-server \
        /opt/spire/bin/spire-server bundle show > conf/downstream-agent/bootstrap.crt

    log-debug "bootstrapping upstream agent..."
    docker compose exec -T spire-server \
        /opt/spire/bin/spire-server bundle show > conf/upstream-agent/bootstrap.crt

    # Register the workload
    log-debug "creating registration entry for upstream workload..."
    docker compose exec -T spire-server \
        /opt/spire/bin/spire-server entry create \
        -parentID "spiffe://domain.test/spire/agent/x509pop/$(fingerprint conf/upstream-agent/agent.crt.pem)" \
        -spiffeID "spiffe://domain.test/upstream-workload" \
        -selector "unix:uid:0" \
        -x509SVIDTTL 0

    log-debug "creating registration entry for downstream workload..."
    docker compose exec -T spire-server \
        /opt/spire/bin/spire-server entry create \
        -parentID "spiffe://domain.test/spire/agent/x509pop/$(fingerprint conf/downstream-agent/agent.crt.pem)" \
        -spiffeID "spiffe://domain.test/downstream-workload" \
        -selector "unix:uid:0" \
        -x509SVIDTTL 0
}

test-envoy() {
    # Ensure connectivity for both TLS and mTLS

    MAXCHECKSPERPORT=15
    CHECKINTERVAL=1

    TRY() { docker compose exec -T downstream-socat-mtls /bin/sh -c 'echo HELLO_MTLS | socat -u STDIN TCP:localhost:8001'; }
    VERIFY() { docker compose exec -T upstream-socat cat /tmp/howdy | grep -q HELLO_MTLS; }

    MTLS_OK=
    for ((i=1;i<=MAXCHECKSPERPORT;i++)); do
        log-debug "Checking MTLS proxy ($i of $MAXCHECKSPERPORT max)..."
        if TRY && VERIFY ; then
            MTLS_OK=1
            log-info "MTLS proxy OK"
            break
        fi
        sleep "${CHECKINTERVAL}"
    done

    TRY() { docker compose exec -T downstream-socat-tls /bin/sh -c 'echo HELLO_TLS | socat -u STDIN TCP:localhost:8002'; }
    VERIFY() { docker compose exec -T upstream-socat cat /tmp/howdy | grep -q HELLO_TLS; }

    TLS_OK=
    for ((i=1;i<=MAXCHECKSPERPORT;i++)); do
        log-debug "Checking TLS proxy ($i of $MAXCHECKSPERPORT max)..."
        if TRY && VERIFY ; then
            TLS_OK=1
            log-info "TLS proxy OK"
            break
        fi
        sleep "${CHECKINTERVAL}"
    done

    if [ -z "${MTLS_OK}" ]; then
        fail-now "MTLS Proxying failed"
    fi

    if [ -z "${TLS_OK}" ]; then
        fail-now "TLS Proxying failed"
    fi
}

"${ROOTDIR}/setup/x509pop/setup.sh" conf/server conf/upstream-agent conf/downstream-agent

# Test at most the last five minor releases.
MAX_ENVOY_RELEASES_TO_TEST=5

# Don't test earlier than v1.13, when was the first release to include the v3
# API.
EARLIEST_ENVOY_RELEASE_TO_TEST=v1.13

envoy-releases

log-info "Releases to test: ${ENVOY_RELEASES_TO_TEST[@]}"

# Do some preliminary setup
setup-tests

# Execute the tests for each release under test. The spire-server should remain
# up across these tests to minimize teardown/setup costs that are tangential
# to the support (since we're only testing the SDS integration).
for release in "${ENVOY_RELEASES_TO_TEST[@]}"; do
    log-info "Building Envoy ${release}..."
    build-mashup-image "${release}"

    log-info "Testing Envoy ${release}..."

    docker-up

    test-envoy

    # stop and clear everything but the server container
    docker compose stop \
        upstream-proxy \
        downstream-proxy \
        upstream-socat \
        downstream-socat-mtls \
        downstream-socat-tls

    docker compose rm -f
done
